/*
 *  Copyright (C) 2012 Компания ВИТ. web: http://diasled.ru Е-mail:  vit@diasled.ru
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package ru.apertum.diasled.forms;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jdesktop.application.Action;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.jdbc.JDBCXYDataset;
import ru.apertum.diasled.common.Uses;
import ru.apertum.diasled.common.exeptions.ClientException;
import ru.apertum.diasled.model.Examination;
import ru.apertum.diasled.model.exam.ColorIndTableCell;
import ru.apertum.diasled.model.exam.ColorIndTableModel;
import ru.apertum.diasled.model.exam.ExamGLEventListener;
import ru.apertum.diasled.model.exam.InsideElements;
import ru.apertum.diasled.model.exam.Shoes;
import ru.apertum.diasled.model.exam.TypeExam;
import ru.apertum.diasled.cfg.Configuration;
import ru.apertum.diasled.model.exam.GinCanvas;
import ru.apertum.diasled.model.exam.IGinClick;
import ru.apertum.diasled.redactor.SensorDraw;

/**
 * Отображение обследования.
 * Показывает проведенное обследование, проводит новое обследование.
 * При старте нового обследования отображает приходящие со сканера данные.
 * Имеет кнопку старта и остановки записи. После проведения записи предлагает сохранить эксперимент.
 * 
 * Эта форма - синглтон. Т.е. в приложени может быть открыта только одна форма этого типа.
 * Сколько бы пользователь не открывал экспериментов, все они будут открываться в одной форме.
 * @author Evgeniy Egorov , Aperum Projects
 */
public class FExamination extends javax.swing.JFrame {

    private Configuration configuration;

    private FExamination() {
        initComponents();
        try {
            setIconImage(ImageIO.read(DiasledView.class.getResource("/ru/apertum/diasled/forms/resources/favicon.png")));
        } catch (IOException ex) {
            System.err.println(ex);
        }
        // свернем по esc
        getRootPane().registerKeyboardAction(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                FGinTools.getInstance().setVisible(false);
                setVisible(false);
            }
        },
                KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
                JComponent.WHEN_IN_FOCUSED_WINDOW);

        final ColorIndTableCell cell = new ColorIndTableCell();
        tableIndicate.setDefaultRenderer(Integer.class, cell);
        tableIndicate.setDefaultRenderer(Double.class, cell);
        tableIndicate.setDefaultRenderer(Color.class, cell);
        tableIndicate.setRowHeight(20);

        //     loadExam();

        examGLEventListener = new ExamGLEventListener(canvasGL, new LayersGetter());
        canvasGL.addGLEventListener(examGLEventListener);
        canvasGL.addMouseMotionListener(examGLEventListener);
        canvasGL.addMouseListener(examGLEventListener);
        canvasGL.addMouseWheelListener(examGLEventListener);
        panelCanvasLeft.add(canvasGL);

        ginCanvas = new GinCanvas();
        ginCanvas.addMouseListener(ginCanvas);
        ginCanvas.addMouseMotionListener(ginCanvas);
        ginCanvas.setBounds(0, 0, 1980, 400);
        panelGIN.removeAll();
        panelGIN.add(ginCanvas);
        ginCanvas.setGinClick(new IGinClick() {

            @Override
            public void mouseClicked(MouseEvent evt, int frameNum) {
                toggleButtonMaxI.setText("Показать максимумы");
                toggleButtonMaxI.setSelected(false);
                int max = -10;
                try {
                    try (Statement stmt = DriverManager.getConnection(Uses.DB_URL, "diasled", "diasled").createStatement()) {
                        final String sql = "SELECT * FROM sensor WHERE exam_id=" + exam.getId() + " and frame_id=" + frameNum;
                        try (ResultSet rs = stmt.executeQuery(sql)) {
                            rs.next();
                            for (SensorDraw sensor : configuration.getSensors()) {
                                sensor.setValue(rs.getInt("s" + sensor.getLogicalNum()));
                                if (max < sensor.getValue()) {
                                    max = sensor.getValue();
                                }
                            }
                        }
                    }
                } catch (Exception ex) {
                    throw new ClientException("не получилось отобразить кадр. ", ex);
                }
                int ww = Math.min(configuration.max_x - configuration.min_x, configuration.max_y - configuration.min_y) / 10;
                configuration.setCoefReductionZ(max / ww);
                checkBoxElemsActionPerformed(null);
            }
        });

        addCanvas();
    }

    public static FExamination getInstance() {
        return NewSingletonHolder.INSTANCE;
    }

    private static class NewSingletonHolder {

        private static final FExamination INSTANCE = new FExamination();
    }
    private Examination exam;

    public void showExam(Examination exam) {
        this.exam = exam;
        if (configuration == null || configuration.getSysNum() != exam.getSysNum().intValue()) {
            configuration = Configuration.loadByID(exam.getSysNum());
        }
        if (configuration == null) {
            throw new ClientException("Не найдена конфигурация для этого обследования. ID устройства " + exam.getSysNum().intValue());
        }
        examGLEventListener.setConfiguration(configuration);
        tableIndicate.setModel(new ColorIndTableModel(configuration.getColorScale()));
        final String examInfo =
                "<span style='font-size:20.0pt;color:red'>&nbsp;Обследование: </span><span style='font-size:16.0pt;color:black'>"
                + TypeExam.getInstance().getStrById(exam.getExamType()) + "<br>&nbsp;<u>Обувь "
                + Shoes.getInstance().getStrById(exam.getShoesType()) + " "
                + InsideElements.getInstance().getStrById(exam.getInsideElement()) + "</u><br>&nbsp;конфигурация " + configuration.getSystemName()
                + "<br>&nbsp;Время. 100 делений = 1 секунда</span>";
        labelPatientInfo.setText("<html>" + examInfo + "<br><br>" + exam.getVisit().getTextInfo() + "<br><br>" + exam.getVisit().getPatient().getTextInfo());
        paintExam();
        setVisible(true);
    }
    private static final GLCanvas canvasGL = new GLCanvas();
    final private ExamGLEventListener examGLEventListener;
    final private GinCanvas ginCanvas;

    /**
     * Класс для передачи отображаемых элементов в канву отрисовки
     */
    public final class LayersGetter {

        public boolean isValume() {
            return checkBoxVolume.isSelected();
        }

        public boolean isOutLine() {
            return checkBoOutline.isSelected();
        }

        public boolean isZone() {
            return checkBoxZone.isSelected();
        }

        public boolean isButterfly() {
            return checkBoxButterfly.isSelected();
        }

        public boolean isPress() {
            return checkBoxPress.isSelected();
        }

        public boolean isIndicators() {
            return checkBoxIndicators.isSelected();
        }
    }
    private final int[] frameMax = new int[256];
    private final ArrayList<Point> butterfly = new ArrayList<>();
    private int coefFrameMax = 1;

    private void paintExam() {
        if (configuration == null) {
            throw new ClientException("Не определена конфигурация при отображении результатов обследования.");
        }
        int cntOutlines = configuration.getOutlines().size();
        cntOutlines = cntOutlines == 0 ? 1 : cntOutlines;
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < cntOutlines; i++) {
            sb.append(",sum_").append(i);
        }

        try {
            Class.forName("org.h2.Driver").newInstance();
            //try (Statement stmt = DriverManager.getConnection("jdbc:mysql://127.0.0.1/hiber?autoReconnect=true&amp;characterEncoding=UTF-8", "root", "root").createStatement()) {
            try (Connection cnt = DriverManager.getConnection(Uses.DB_URL, "diasled", "diasled")) {
                //  с начала загрузим кадр с максимумами на всех серсорах
                final StringBuilder sbm = new StringBuilder();
                for (int i = 0; i < 256; i++) {
                    sbm.append(",max(s").append(i).append(") ms").append(i).append("");
                }
                String sql = "SELECT " + sbm.substring(1) + " FROM SENSOR where EXAM_ID =" + exam.getId();
                int max = -10;
                try (ResultSet rs = cnt.createStatement().executeQuery(sql)) {
                    rs.next();
                    for (SensorDraw sensor : configuration.getSensors()) {
                        sensor.setValue(rs.getInt("ms" + sensor.getLogicalNum()));
                        frameMax[sensor.getLogicalNum()] = sensor.getValue();
                        if (max < sensor.getValue()) {
                            max = sensor.getValue();
                        }
                    }
                }
                int ww = Math.min(configuration.max_x - configuration.min_x, configuration.max_y - configuration.min_y) / 10;
                coefFrameMax = max / ww;
                configuration.setCoefReductionZ(coefFrameMax);
                // теперь координаты ломаной бабочки
                sql = "SELECT b_x, b_y FROM SENSOR where EXAM_ID =" + exam.getId();
                try (ResultSet rs = cnt.createStatement().executeQuery(sql)) {
                    butterfly.clear();
                    while (rs.next()) {
                        butterfly.add(new Point(rs.getInt("b_x"), rs.getInt("b_y")));
                    }

                    examGLEventListener.setButterfly(butterfly);
                }

                // отрисуем ГИН
                sql = "SELECT frame_id" + sb.toString() + " FROM sensor WHERE exam_id=" + exam.getId();
                try (ResultSet rs = cnt.createStatement().executeQuery(sql)) {
                    final int[][] data = new int[exam.getDuration() * 100 + 500][cntOutlines];
                    int j = 0;
                    while (rs.next()) {
                        for (int i = 0; i < cntOutlines; i++) {
                            data[j][i] = rs.getInt("sum_" + i);

                        }
                        j++;
                    }
                    ginCanvas.setData(data, exam);
                }


            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException except) {
            Uses.log.logger.error("Indexes!", except);
        }
        // addCanvas();
    }
    Canvas canvas;

    private void addCanvas() {
        panelBottomDraw.removeAll();
        canvas = new Canvas() {

            @Override
            public void paint(Graphics g) {
                int h = 10;
                for (int y = 1; y <= h * 8 + 3; y = y + h) {
                    g.drawLine(0, y, getWidth(), y);
                }
            }
        };
        canvas.setBounds(0, 0, 2000, 1250);
        panelBottomDraw.add(canvas);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel3 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        labelPatientInfo = new javax.swing.JLabel();
        panelColorInd = new javax.swing.JPanel();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();
        buttonMaxDown = new javax.swing.JButton();
        buttonMaxUp = new javax.swing.JButton();
        buttonMinDown = new javax.swing.JButton();
        buttonMinUp = new javax.swing.JButton();
        buttonAutoMax = new javax.swing.JButton();
        buttonAutoMin = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        tableIndicate = new javax.swing.JTable();
        jPanel7 = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        checkBoxVolume = new javax.swing.JCheckBox();
        checkBoOutline = new javax.swing.JCheckBox();
        checkBoxButterfly = new javax.swing.JCheckBox();
        checkBoxPress = new javax.swing.JCheckBox();
        checkBoxIndicators = new javax.swing.JCheckBox();
        checkBoxZone = new javax.swing.JCheckBox();
        buttonReturnProjection = new javax.swing.JButton();
        toggleButtonMaxI = new javax.swing.JToggleButton();
        buttonShowGinTools = new javax.swing.JButton();
        panelCanvasLeft = new javax.swing.JPanel();
        panelGIN = new javax.swing.JPanel();
        panelBottomDraw = new javax.swing.JPanel();

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(ru.apertum.diasled.Diasled.class).getContext().getResourceMap(FExamination.class);
        setTitle(resourceMap.getString("Form.title")); // NOI18N
        setName("Form"); // NOI18N
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });

        jPanel3.setBorder(new javax.swing.border.MatteBorder(null));
        jPanel3.setName("jPanel3"); // NOI18N

        jScrollPane1.setBorder(new javax.swing.border.MatteBorder(null));
        jScrollPane1.setName("jScrollPane1"); // NOI18N

        labelPatientInfo.setText(resourceMap.getString("labelPatientInfo.text")); // NOI18N
        labelPatientInfo.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        labelPatientInfo.setName("labelPatientInfo"); // NOI18N
        jScrollPane1.setViewportView(labelPatientInfo);

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 410, Short.MAX_VALUE)
        );

        panelColorInd.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        panelColorInd.setName("panelColorInd"); // NOI18N
        panelColorInd.setPreferredSize(new java.awt.Dimension(109, 380));

        jButton3.setIcon(resourceMap.getIcon("jButton3.icon")); // NOI18N
        jButton3.setText(resourceMap.getString("jButton3.text")); // NOI18N
        jButton3.setName("jButton3"); // NOI18N

        jButton4.setIcon(resourceMap.getIcon("jButton4.icon")); // NOI18N
        jButton4.setText(resourceMap.getString("jButton4.text")); // NOI18N
        jButton4.setName("jButton4"); // NOI18N

        jButton5.setIcon(resourceMap.getIcon("jButton5.icon")); // NOI18N
        jButton5.setName("jButton5"); // NOI18N

        jButton6.setIcon(resourceMap.getIcon("jButton6.icon")); // NOI18N
        jButton6.setName("jButton6"); // NOI18N

        buttonMaxDown.setIcon(resourceMap.getIcon("buttonMaxDown.icon")); // NOI18N
        buttonMaxDown.setName("buttonMaxDown"); // NOI18N
        buttonMaxDown.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                coloreScaleChange(evt);
            }
        });

        buttonMaxUp.setIcon(resourceMap.getIcon("buttonMaxUp.icon")); // NOI18N
        buttonMaxUp.setName("buttonMaxUp"); // NOI18N
        buttonMaxUp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                coloreScaleChange(evt);
            }
        });

        buttonMinDown.setIcon(resourceMap.getIcon("buttonMinDown.icon")); // NOI18N
        buttonMinDown.setName("buttonMinDown"); // NOI18N
        buttonMinDown.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                coloreScaleChange(evt);
            }
        });

        buttonMinUp.setIcon(resourceMap.getIcon("buttonMinUp.icon")); // NOI18N
        buttonMinUp.setName("buttonMinUp"); // NOI18N
        buttonMinUp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                coloreScaleChange(evt);
            }
        });

        buttonAutoMax.setText(resourceMap.getString("buttonAutoMax.text")); // NOI18N
        buttonAutoMax.setName("buttonAutoMax"); // NOI18N
        buttonAutoMax.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonAutoMaxActionPerformed(evt);
            }
        });

        buttonAutoMin.setText(resourceMap.getString("buttonAutoMin.text")); // NOI18N
        buttonAutoMin.setName("buttonAutoMin"); // NOI18N
        buttonAutoMin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonAutoMinActionPerformed(evt);
            }
        });

        jScrollPane2.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane2.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
        jScrollPane2.setName("jScrollPane2"); // NOI18N

        tableIndicate.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3"
            }
        ));
        tableIndicate.setAutoscrolls(false);
        tableIndicate.setName("tableIndicate"); // NOI18N
        tableIndicate.setRequestFocusEnabled(false);
        tableIndicate.setRowHeight(30);
        tableIndicate.setRowMargin(0);
        tableIndicate.setRowSelectionAllowed(false);
        tableIndicate.setShowHorizontalLines(false);
        tableIndicate.setTableHeader(null);
        tableIndicate.addHierarchyBoundsListener(new java.awt.event.HierarchyBoundsListener() {
            public void ancestorMoved(java.awt.event.HierarchyEvent evt) {
            }
            public void ancestorResized(java.awt.event.HierarchyEvent evt) {
                tableIndicateAncestorResized(evt);
            }
        });
        jScrollPane2.setViewportView(tableIndicate);
        tableIndicate.getColumnModel().getColumn(0).setResizable(false);
        tableIndicate.getColumnModel().getColumn(0).setHeaderValue(resourceMap.getString("tableIndicate.columnModel.title0")); // NOI18N
        tableIndicate.getColumnModel().getColumn(1).setResizable(false);
        tableIndicate.getColumnModel().getColumn(1).setHeaderValue(resourceMap.getString("tableIndicate.columnModel.title1")); // NOI18N
        tableIndicate.getColumnModel().getColumn(2).setResizable(false);
        tableIndicate.getColumnModel().getColumn(2).setHeaderValue(resourceMap.getString("tableIndicate.columnModel.title2")); // NOI18N

        javax.swing.GroupLayout panelColorIndLayout = new javax.swing.GroupLayout(panelColorInd);
        panelColorInd.setLayout(panelColorIndLayout);
        panelColorIndLayout.setHorizontalGroup(
            panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelColorIndLayout.createSequentialGroup()
                .addGroup(panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 95, Short.MAX_VALUE)
                    .addGroup(panelColorIndLayout.createSequentialGroup()
                        .addGroup(panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jButton6, 0, 0, Short.MAX_VALUE)
                            .addComponent(jButton5, 0, 0, Short.MAX_VALUE)
                            .addComponent(jButton4, 0, 0, Short.MAX_VALUE)
                            .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 27, Short.MAX_VALUE))
                        .addGap(0, 0, 0)
                        .addGroup(panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(buttonAutoMax, javax.swing.GroupLayout.DEFAULT_SIZE, 39, Short.MAX_VALUE)
                            .addComponent(buttonAutoMin, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGap(0, 0, 0)
                        .addGroup(panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(buttonMaxDown, javax.swing.GroupLayout.PREFERRED_SIZE, 29, Short.MAX_VALUE)
                            .addComponent(buttonMaxUp, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 29, Short.MAX_VALUE)
                            .addComponent(buttonMinUp, javax.swing.GroupLayout.PREFERRED_SIZE, 29, Short.MAX_VALUE)
                            .addComponent(buttonMinDown, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 29, Short.MAX_VALUE))))
                .addContainerGap())
        );
        panelColorIndLayout.setVerticalGroup(
            panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelColorIndLayout.createSequentialGroup()
                .addGroup(panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(panelColorIndLayout.createSequentialGroup()
                        .addComponent(buttonMaxUp)
                        .addGap(0, 0, 0)
                        .addComponent(buttonMaxDown))
                    .addGroup(panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addGroup(panelColorIndLayout.createSequentialGroup()
                            .addComponent(jButton3)
                            .addGap(0, 0, 0)
                            .addComponent(jButton4))
                        .addComponent(buttonAutoMax, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 344, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelColorIndLayout.createSequentialGroup()
                        .addComponent(buttonMinUp)
                        .addGap(0, 0, 0)
                        .addComponent(buttonMinDown))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelColorIndLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addGroup(panelColorIndLayout.createSequentialGroup()
                            .addComponent(jButton5)
                            .addGap(0, 0, 0)
                            .addComponent(jButton6))
                        .addComponent(buttonAutoMin, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
        );

        jPanel7.setBorder(new javax.swing.border.MatteBorder(null));
        jPanel7.setName("jPanel7"); // NOI18N

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(resourceMap.getString("jPanel1.border.title"))); // NOI18N
        jPanel1.setName("jPanel1"); // NOI18N

        checkBoxVolume.setSelected(true);
        checkBoxVolume.setText(resourceMap.getString("checkBoxVolume.text")); // NOI18N
        checkBoxVolume.setName("checkBoxVolume"); // NOI18N
        checkBoxVolume.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                checkBoxElemsActionPerformed(evt);
            }
        });

        checkBoOutline.setSelected(true);
        checkBoOutline.setText(resourceMap.getString("checkBoOutline.text")); // NOI18N
        checkBoOutline.setName("checkBoOutline"); // NOI18N
        checkBoOutline.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                checkBoxElemsActionPerformed(evt);
            }
        });

        checkBoxButterfly.setSelected(true);
        checkBoxButterfly.setText(resourceMap.getString("checkBoxButterfly.text")); // NOI18N
        checkBoxButterfly.setName("checkBoxButterfly"); // NOI18N
        checkBoxButterfly.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                checkBoxElemsActionPerformed(evt);
            }
        });

        checkBoxPress.setSelected(true);
        checkBoxPress.setText(resourceMap.getString("checkBoxPress.text")); // NOI18N
        checkBoxPress.setName("checkBoxPress"); // NOI18N
        checkBoxPress.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                checkBoxElemsActionPerformed(evt);
            }
        });

        checkBoxIndicators.setSelected(true);
        checkBoxIndicators.setText(resourceMap.getString("checkBoxIndicators.text")); // NOI18N
        checkBoxIndicators.setName("checkBoxIndicators"); // NOI18N
        checkBoxIndicators.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                checkBoxElemsActionPerformed(evt);
            }
        });

        checkBoxZone.setSelected(true);
        checkBoxZone.setText(resourceMap.getString("checkBoxZone.text")); // NOI18N
        checkBoxZone.setName("checkBoxZone"); // NOI18N
        checkBoxZone.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                checkBoxElemsActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(checkBoxVolume)
                    .addComponent(checkBoOutline)
                    .addComponent(checkBoxZone)
                    .addComponent(checkBoxButterfly)
                    .addComponent(checkBoxPress)
                    .addComponent(checkBoxIndicators))
                .addContainerGap(17, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(checkBoxVolume)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoOutline)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxZone)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxButterfly)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxPress)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxIndicators))
        );

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(ru.apertum.diasled.Diasled.class).getContext().getActionMap(FExamination.class, this);
        buttonReturnProjection.setAction(actionMap.get("returnProjection")); // NOI18N
        buttonReturnProjection.setText(resourceMap.getString("buttonReturnProjection.text")); // NOI18N
        buttonReturnProjection.setName("buttonReturnProjection"); // NOI18N

        toggleButtonMaxI.setAction(actionMap.get("showFrame")); // NOI18N
        toggleButtonMaxI.setName("toggleButtonMaxI"); // NOI18N

        buttonShowGinTools.setText(resourceMap.getString("buttonShowGinTools.text")); // NOI18N
        buttonShowGinTools.setName("buttonShowGinTools"); // NOI18N
        buttonShowGinTools.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonShowGinToolsActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7);
        jPanel7.setLayout(jPanel7Layout);
        jPanel7Layout.setHorizontalGroup(
            jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel7Layout.createSequentialGroup()
                .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(toggleButtonMaxI, javax.swing.GroupLayout.PREFERRED_SIZE, 147, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(buttonReturnProjection)
                    .addGroup(jPanel7Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(buttonShowGinTools)))
                .addContainerGap(18, Short.MAX_VALUE))
        );
        jPanel7Layout.setVerticalGroup(
            jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel7Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(toggleButtonMaxI)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(buttonReturnProjection)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 146, Short.MAX_VALUE)
                .addComponent(buttonShowGinTools)
                .addContainerGap())
        );

        panelCanvasLeft.setBorder(new javax.swing.border.MatteBorder(null));
        panelCanvasLeft.setName("panelCanvasLeft"); // NOI18N
        panelCanvasLeft.setPreferredSize(new java.awt.Dimension(380, 380));
        panelCanvasLeft.addHierarchyBoundsListener(new java.awt.event.HierarchyBoundsListener() {
            public void ancestorMoved(java.awt.event.HierarchyEvent evt) {
            }
            public void ancestorResized(java.awt.event.HierarchyEvent evt) {
                panelCanvasLeftAncestorResized(evt);
            }
        });

        javax.swing.GroupLayout panelCanvasLeftLayout = new javax.swing.GroupLayout(panelCanvasLeft);
        panelCanvasLeft.setLayout(panelCanvasLeftLayout);
        panelCanvasLeftLayout.setHorizontalGroup(
            panelCanvasLeftLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 424, Short.MAX_VALUE)
        );
        panelCanvasLeftLayout.setVerticalGroup(
            panelCanvasLeftLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 410, Short.MAX_VALUE)
        );

        panelGIN.setBackground(resourceMap.getColor("panelGIN.background")); // NOI18N
        panelGIN.setBorder(new javax.swing.border.MatteBorder(null));
        panelGIN.setName("panelGIN"); // NOI18N
        panelGIN.addHierarchyBoundsListener(new java.awt.event.HierarchyBoundsListener() {
            public void ancestorMoved(java.awt.event.HierarchyEvent evt) {
            }
            public void ancestorResized(java.awt.event.HierarchyEvent evt) {
                panelGINAncestorResized(evt);
            }
        });

        javax.swing.GroupLayout panelGINLayout = new javax.swing.GroupLayout(panelGIN);
        panelGIN.setLayout(panelGINLayout);
        panelGINLayout.setHorizontalGroup(
            panelGINLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 1080, Short.MAX_VALUE)
        );
        panelGINLayout.setVerticalGroup(
            panelGINLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 214, Short.MAX_VALUE)
        );

        panelBottomDraw.setBackground(resourceMap.getColor("panelBottomDraw.background")); // NOI18N
        panelBottomDraw.setBorder(new javax.swing.border.MatteBorder(null));
        panelBottomDraw.setName("panelBottomDraw"); // NOI18N

        javax.swing.GroupLayout panelBottomDrawLayout = new javax.swing.GroupLayout(panelBottomDraw);
        panelBottomDraw.setLayout(panelBottomDrawLayout);
        panelBottomDrawLayout.setHorizontalGroup(
            panelBottomDrawLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 1080, Short.MAX_VALUE)
        );
        panelBottomDrawLayout.setVerticalGroup(
            panelBottomDrawLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 77, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(panelColorInd, javax.swing.GroupLayout.PREFERRED_SIZE, 99, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(panelCanvasLeft, javax.swing.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addComponent(panelBottomDraw, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(panelGIN, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(panelCanvasLeft, javax.swing.GroupLayout.DEFAULT_SIZE, 412, Short.MAX_VALUE)
                    .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(panelColorInd, javax.swing.GroupLayout.DEFAULT_SIZE, 412, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(panelGIN, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(panelBottomDraw, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void tableIndicateAncestorResized(java.awt.event.HierarchyEvent evt) {//GEN-FIRST:event_tableIndicateAncestorResized
        int h = tableIndicate.getParent().getHeight() / tableIndicate.getRowCount();
        tableIndicate.setRowHeight(h < 16 ? 16 : h);
    }//GEN-LAST:event_tableIndicateAncestorResized

    private void panelCanvasLeftAncestorResized(java.awt.event.HierarchyEvent evt) {//GEN-FIRST:event_panelCanvasLeftAncestorResized
        canvasGL.setBounds(0, 0, panelCanvasLeft.getWidth(), panelCanvasLeft.getHeight());
    }//GEN-LAST:event_panelCanvasLeftAncestorResized

    private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                canvas.repaint();
                canvasGL.repaint();
            }
        });
    }

    @Action
    public void returnProjection() {
        examGLEventListener.setRotateZero();
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                canvasGL.repaint();
            }
        });
    }

    @Action
    public void showFrame() {
        for (SensorDraw sensor : configuration.getSensors()) {
            sensor.setValue(frameMax[sensor.getLogicalNum()]);
        }
        checkBoxElemsActionPerformed(null);
        toggleButtonMaxI.setText("Текущий кадр");
    }

    /*
    }//GEN-LAST:event_formComponentResized
     */
    private void checkBoxElemsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkBoxElemsActionPerformed
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                canvasGL.repaint();
            }
        });
    }//GEN-LAST:event_checkBoxElemsActionPerformed

    private void coloreScaleChange(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_coloreScaleChange

        if (evt.getSource().hashCode() == buttonMaxUp.hashCode()) {
            configuration.getColorScale().incMax();
        }
        if (evt.getSource().hashCode() == buttonMaxDown.hashCode()) {
            configuration.getColorScale().decMax();
        }
        if (evt.getSource().hashCode() == buttonMinUp.hashCode()) {
            configuration.getColorScale().incMin();
        }
        if (evt.getSource().hashCode() == buttonMinDown.hashCode()) {
            configuration.getColorScale().decMin();
        }
        ((ColorIndTableModel) tableIndicate.getModel()).fireTableDataChanged();
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                canvasGL.repaint();
            }
        });

    }//GEN-LAST:event_coloreScaleChange

    private void buttonAutoMaxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAutoMaxActionPerformed
        configuration.getColorScale().setMax(((ColorIndTableModel) tableIndicate.getModel()).getMax());
        ((ColorIndTableModel) tableIndicate.getModel()).fireTableDataChanged();
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                canvasGL.repaint();
            }
        });
    }//GEN-LAST:event_buttonAutoMaxActionPerformed

    private void buttonAutoMinActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAutoMinActionPerformed
        configuration.getColorScale().setMin(((ColorIndTableModel) tableIndicate.getModel()).getMin());
        ((ColorIndTableModel) tableIndicate.getModel()).fireTableDataChanged();
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                canvasGL.repaint();
            }
        });
    }//GEN-LAST:event_buttonAutoMinActionPerformed

    private void panelGINAncestorResized(java.awt.event.HierarchyEvent evt) {//GEN-FIRST:event_panelGINAncestorResized
        if (ginCanvas != null) {
            ginCanvas.setBounds(0, 0, panelGIN.getWidth(), panelGIN.getHeight());
        }
    }//GEN-LAST:event_panelGINAncestorResized

    private void buttonShowGinToolsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonShowGinToolsActionPerformed
        final FGinTools oz = FGinTools.getInstance();
        oz.setCanvas(ginCanvas);
        oz.setLocationRelativeTo(null);
        oz.setLocation(getLocation().x + getWidth() - oz.getWidth() - 20, getLocation().y + 70);
        oz.setVisible(true);
    }//GEN-LAST:event_buttonShowGinToolsActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        FGinTools.getInstance().setVisible(false);
    }//GEN-LAST:event_formWindowClosing
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton buttonAutoMax;
    private javax.swing.JButton buttonAutoMin;
    private javax.swing.JButton buttonMaxDown;
    private javax.swing.JButton buttonMaxUp;
    private javax.swing.JButton buttonMinDown;
    private javax.swing.JButton buttonMinUp;
    private javax.swing.JButton buttonReturnProjection;
    private javax.swing.JButton buttonShowGinTools;
    private javax.swing.JCheckBox checkBoOutline;
    private javax.swing.JCheckBox checkBoxButterfly;
    private javax.swing.JCheckBox checkBoxIndicators;
    private javax.swing.JCheckBox checkBoxPress;
    private javax.swing.JCheckBox checkBoxVolume;
    private javax.swing.JCheckBox checkBoxZone;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JButton jButton6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JLabel labelPatientInfo;
    private javax.swing.JPanel panelBottomDraw;
    private javax.swing.JPanel panelCanvasLeft;
    private javax.swing.JPanel panelColorInd;
    private javax.swing.JPanel panelGIN;
    private javax.swing.JTable tableIndicate;
    private javax.swing.JToggleButton toggleButtonMaxI;
    // End of variables declaration//GEN-END:variables
}
